<script setup>

import {ref, onMounted, watch, computed} from 'vue';
import axios from "axios";
import {snackbar} from './store'
// 导入依赖
import VueOfficeDocx from "@vue-office/docx";
// 导入样式文件
import "@vue-office/docx/lib/index.css";

// 查询
const itemsPerPage = ref(10);
const pageNo = ref(1);
const headers = [
    {title: '序号', key: 'num', sortable: false},
    {title: '活动名称', key: 'activityId', sortable: false},
    // {title: '攻方人员', key: 'attackUserId', sortable: false},
    {title: '攻方企业', key: 'attackId', sortable: false},
    {title: '防守企业', key: 'defendName', sortable: false},
    {title: '被攻击系统名称', key: 'systemName', sortable: false},
    {title: '打分状态', key: 'scoreStatus', sortable: false},
    {title: '分数', key: 'score', sortable: false},
    {title: '创建时间', key: 'createTime', sortable: false},
    {title: '操作', key: 'actions', sortable: false}
];
const companyList = ref([
    {value:'48',title:'党委机关'},
    {value:'50',title:'事业单位'},
    {value:'51',title:'电子政务'},
    {value:'52',title:'政府机关'},
    {value:'53',title:'大型国企'},
    {value:'54',title:'其他单位'}
]);
const userInfo = ref(JSON.parse(localStorage.getItem("ZAYY_USER_INFO")));
const userList = ref([]);
const activityList = ref([]);
const defendList = ref([]);
const attackList = ref([]);
const networkLevelList = ref([]);
const systemNameList = ref([]);
const errorLevelList = ref([]);
const errorTypeList = ref([]);
const dataTypeList = ref([]);
const judgeList = ref([]);
const items = ref([]);
const loading = ref(true);
const totalItems = ref(0);

const search = ref('');
const activityName = ref(JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).activityId);
const attackName = ref(JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).attackId);
const defendName = ref(null);
const judgeName = ref(null);
const code = ref(null);
watch(activityName, () => {
    search.value = activityName.value
    getDefenceInfo()
})
watch(attackName, () => {
    search.value = attackName.value
    loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
    getDefenceInfo()
})
watch(defendName, () => {
    search.value = defendName.value
    loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
})
watch(judgeName, () => {
    search.value = judgeName.value
})
watch(code, () => {
    search.value = code.value
})

function loadItems({page, itemsPerPage}) {
    pageNo.value = page
    loading.value = true;
    axios.post('/attackRecord/select', {
        pageNo: pageNo.value,
        pageSize: itemsPerPage,
        scoreStatus: code.value,
        attackUserId: userInfo.value.userType == 3 ? null : userInfo.value.id,
        activityId: activityName.value,
        defendId: defendName.value,
        attackId: attackName.value,
        judgeId: judgeName.value
    }).then(res => {
        items.value = res.data.records;
        totalItems.value = res.data.total;
        loading.value = false;
    })
}

onMounted(() => {
    axios.post("/user/selectPage", {pageNo:1,pageSize:10000}).then(res => {
        userList.value = res.data.records
    })
    axios.post("/basJudge/selectPage", {pageNo:1,pageSize:1000}).then(res => {
        judgeList.value = res.data.records
    })
    axios.post("/activity/select", {pageNo:1,pageSize:1000}).then(res => {
        activityList.value = res.data.records
    })
    getDefenceInfo()
    getAttackInfo()
    axios.post("/sysDict/select", {pageNo:1,pageSize:1000,dictType:"WLCJ"}).then(res => {
        networkLevelList.value = res.data.records
    })
    axios.post("/sysDict/select", {pageNo:1,pageSize:1000,dictType:"XXXTLB"}).then(res => {
        systemNameList.value = res.data.records
    })
    axios.post("/sysDict/select", {pageNo:1,pageSize:1000,dictType:"YHJB"}).then(res => {
        errorLevelList.value = res.data.records
    })
    axios.post("/sysDict/select", {pageNo:1,pageSize:1000,dictType:"LDLB"}).then(res => {
        errorTypeList.value = res.data.records
    })
    axios.post("/sysDict/select", {pageNo:1,pageSize:1000,dictType:"SJLX"}).then(res => {
        dataTypeList.value = res.data.records
    })
});

const getDefenceInfo = () => {
    axios.post('/companyAttack/findAttackDefenceInfo', {
        activityId: userInfo.value.activityId || activityName.value,
        id: userInfo.value.attackId || attackName.value
    }).then(res => {
        defendList.value = res.data.privateDefendInfo.concat(res.data.publicDefendInfo)
    }, err => {
        defendList.value = []
    })
}

const getAttackInfo = () => {
    axios.post("/companyAttack/select", {pageNo:1,pageSize:10000}).then(res => {
        attackList.value = res.data.records
    })
}

// 增改
const isShowDialog = ref(false)
const dialogEnum = {
    update: '编辑',
    create: '新增攻防记录'
}
const dialogType = ref(null)
const isShowDeleteDialog = ref(false)
const editedItem = ref({
    "activityId": JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).activityId,
    "defendId": "",
    "attackId": JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).attackId,
    "systemName": "",
    "attackUserId": JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).userId,
    "networkLevelId":"",
    "systemTypeId":"",
    "errorLevelId":"",
    "errorTypeId":"",
    "errorIp":"",
    "dataTypeId":"",
    "dataCount":"",
    "remark":"",
    "repairRemark": "",
    "file": []
});

function resetEditedItem() {
    editedItem.value = {
        "activityId": JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).activityId,
        "defendId": "",
        "attackId": JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).attackId,
        "systemName": "",
        "attackUserId": JSON.parse(localStorage.getItem("ZAYY_USER_INFO")).userId,
        "networkLevelId":"",
        "systemTypeId":"",
        "errorLevelId":"",
        "errorTypeId":"",
        "errorIp":"",
        "dataTypeId":"",
        "dataCount":"",
        "remark":"",
        "repairRemark": "",
        "file": []
    }
}

function clickNew() {
    resetEditedItem()
    dialogType.value = dialogEnum.create
    isShowDialog.value = true
}

function close() {
    isShowDialog.value = false
    resetEditedItem()
    dialogType.value = null
}

function clickEdit(item) {
    editedItem.value = Object.assign({}, item)
    editedItem.value.status += ""
    editedItem.value.companyType += ""
    editedItem.value.fileList = [{name:editedItem.value.file}]
    isShowDialog.value = true
    dialogType.value = dialogEnum.update
}

function save() {
    if (dialogType.value === dialogEnum.update) {
        axios({
            method: 'POST',
            url: '/attackRecord/update',
            data: editedItem.value
        }).then(() => {
            snackbar.info('编辑成功')
            close()
            loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
        })
    } else if (dialogType.value === dialogEnum.create) {
        axios({
            method: 'POST',
            url: '/attackRecord/save',
            data: editedItem.value
        }).then((res) => {
            snackbar.info('创建成功')
            close()
            loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
        })
    }
}

// 删
const beDeleteItem = ref({})

function clickDelete(item) {
    isShowDeleteDialog.value = true
    beDeleteItem.value = item
}

function clickDeleteConfirm() {
    axios.post('/basJudge/delBasJudge?userId=' + beDeleteItem.value.id).then(() => {
        snackbar.info("删除成功")
        loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
        clickCloseDelete()
    })
}

function clickCloseDelete() {
    isShowDeleteDialog.value = false
    beDeleteItem.value = null
}

function uploadFile() {
    if(1) {
        var formData = new FormData();
        formData.append('file', editedItem.value.fileList)
        // formData.append('activityId', 6)
        formData.append('activityId', userInfo.value.activityId)
        axios({
            method: "POST",
            url: "/attackRecord/uploadFile",
            data: formData,
            headers: {
                'Content-Type': "multipart/form-data"
            }
        }).then(res => {
            if(res.code == 200) {
                snackbar.info("上传成功")
                editedItem.value.file = res.data
            } else if(res.code == 500) {
                editedItem.value.fileList = []
                snackbar.info(res.message)
            }
        }, err => {
            console.log(err)
        })
    }
}

const baseUrl = ref("http://101.68.222.195:8099/netDefense/");
const htmlShow = ref(false);
const docxSrc = ref("");
function clickCheck(val) {
    let url = `${baseUrl.value}whiteApi/${val.activityId}&${val.file}`
    docxSrc.value = url
    htmlShow.value = true
}

const scoreShow = ref(false);
const scoreItem = ref({});
const score = ref(50);
function clickScore(row) {
    let defendArr = []
    axios.post('/companyAttack/findAttackDefenceInfo', {
        activityId: userInfo.value.activityId,
        id: row.attackId
    }).then(res => {
        defendArr = res.data.privateDefendInfo.concat(res.data.publicDefendInfo)
        defendArr.forEach(k => {
            if(k.id == scoreItem.value.defendId) {
                scoreItem.value.defendName = k.companyName
            }
        })        
    })
    scoreItem.value = row
    scoreShow.value = true
    score.value = 50
    activityList.value.forEach(k => {
        if(k.id == scoreItem.value.activityId) {
            scoreItem.value.activityName = k.name
        }
    })
    attackList.value.forEach(k => {
        if(k.id == scoreItem.value.attackId) {
            scoreItem.value.attackName = k.companyName
        }
    })
}

function saveScroe(val) {
    let obj = {
        judgeId: userInfo.value.userId,
        userType: 2,
        recordId: val.id,
        score: score.value
    }
    axios.post("/attackRecord/setScore", obj).then(res => {
        snackbar.info('打分成功')
        scoreShow.value = false
        loadItems({page: pageNo.value, itemsPerPage: itemsPerPage.value})
    })
}

function clickDownload(val) {
    let url = `${baseUrl.value}whiteApi/${val.activityId}&${val.file}`
    location.href = url
}

function clickDownloadWord() {
    console.log("尝试下载文件...");
    const attachmentUrl = "/publicWord.docx";
    const link = document.createElement("a");
    link.href = attachmentUrl;
    link.download = "漏洞模板.docx";
    document.body.appendChild(link); // 很重要，添加到 DOM
    link.click();
    document.body.removeChild(link); // 下载完后移除
}

const zipItem = ref({})
const zipShow = ref(false)
function clickZip(item) {
    zipItem.value = item
    zipShow.value = true
}

function saveZip() {
    let obj = {
        id: zipItem.value.activityId,
        contactName: zipItem.value.contactName,
        contactPhone: zipItem.value.contactPhone
    }
    axios({
        method: "POST",
        url: "/activity/generateReport",
        responseType: 'blob',
        data: obj
    }).then(res => {
        console.log(res.data)
    }, err => {
        let blob = new Blob([err.data], {type: "application/zip"});
        let fileName = `下载报告.zip`
        if ("download" in document.createElement("a")) {
            // 支持a标签download的浏览器
            const link = document.createElement("a"); // 创建a标签
            link.download = fileName; // a标签添加属性
            link.style.display = "none";
            link.href = URL.createObjectURL(blob);
            document.body.appendChild(link);
            link.click(); // 执行下载
            URL.revokeObjectURL(link.href); // 释放url
            document.body.removeChild(link); // 释放标签
        } else {
            // 其他浏览器
            navigator.msSaveBlob(blob, fileName);
        }
    })
}
</script>

<template>
    <v-toolbar density="compact">
        <v-toolbar-title>攻防记录管理</v-toolbar-title>
        <v-autocomplete
        v-model="activityName"
        :items=activityList
        item-title="name"
        item-value="id"
        :clearable="userInfo.userType == 1 ? true : false"
        hide-details
        :readonly="userInfo.userType != 1"
        label="查询活动"></v-autocomplete>
        <v-autocomplete
        v-model="attackName"
        :items=attackList
        item-title="companyName"
        item-value="id"
        :clearable="userInfo.userType != 3 ? true : false"
        hide-details
        :readonly="userInfo.userType == 3"
        label="查询攻方企业"></v-autocomplete>
        <v-autocomplete
        v-model="defendName"
        :items=defendList
        item-title="companyName"
        item-value="id"
        :clearable="true"
        hide-details
        label="查询防守企业"></v-autocomplete>
        <v-autocomplete
        v-model="judgeName"
        :items=judgeList
        item-title="name"
        item-value="id"
        :clearable="true"
        hide-details
        label="查询裁判"></v-autocomplete>
        <v-select
        :items="[{value:'1',title:'待打分'},{value:'2',title:'已打分'}]"
        v-model="code"
        :clearable="true"
        hide-details
        label="打分条件"></v-select>
        <v-dialog v-model="isShowDialog" max-width="1000px">
            <template v-slot:activator="{ props }" v-if="userInfo.userType == 3">
                <v-btn icon="mdi-plus" v-on:click="clickNew" v-bind="props"></v-btn>
            </template>
            <v-card>
                <v-card-title>{{ dialogType }}</v-card-title>
                <v-card-text>
                    <v-row>
                        <v-col cols="12" md="6">
                            <v-select
                            :items=activityList
                            v-model="editedItem.activityId"
                            label="参加活动"
                            item-title="name"
                            item-value="id"
                            readonly
                            required></v-select>                            
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-select
                            :items=attackList
                            v-model="editedItem.attackId"
                            label="攻方企业"
                            item-title="companyName"
                            item-value="id"
                            readonly
                            required></v-select>                            
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-autocomplete
                            :items=defendList
                            v-model="editedItem.defendId"
                            label="防守企业"
                            item-title="companyName"
                            item-value="id"
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            >
                                <!-- <template v-slot:item="{props,item}">
                                    <v-list-item v-bind="props" :subtitle="item.raw.companyName"></v-list-item>
                                </template> -->
                            </v-autocomplete>                            
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-text-field v-model="editedItem.systemName" label="被攻击系统名称" required></v-text-field>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-autocomplete
                            :items=systemNameList
                            v-model="editedItem.systemTypeId"
                            label="被攻击系统类别"
                            item-title="dictLabel"
                            item-value="dictCode"
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            ></v-autocomplete>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-autocomplete
                            :items=networkLevelList
                            v-model="editedItem.networkLevelId"
                            label="网络层级"
                            item-title="dictLabel"
                            item-value="dictCode"
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            ></v-autocomplete>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-autocomplete
                            :items=errorLevelList
                            v-model="editedItem.errorLevelId"
                            label="隐患级别"
                            item-title="dictLabel"
                            item-value="dictCode"
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            ></v-autocomplete>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-autocomplete
                            :items=errorTypeList
                            v-model="editedItem.errorTypeId"
                            label="隐患类型"
                            item-title="dictLabel"
                            item-value="dictCode"
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            ></v-autocomplete>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-text-field v-model="editedItem.errorIp" label="隐患IP或域名信息" required></v-text-field>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-autocomplete
                            :items=dataTypeList
                            v-model="editedItem.dataTypeId"
                            label="数据类型"
                            item-title="dictLabel"
                            item-value="dictCode"
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            ></v-autocomplete>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-text-field :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update" v-model="editedItem.dataCount" label="数据量" required></v-text-field>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-text-field :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update" v-model="editedItem.remark" label="漏洞描述" required></v-text-field>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-file-input
                            :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update"
                            v-model="editedItem.fileList"
                            label="漏洞信息"
                            show-size
                            @change="uploadFile"
                            prepend-icon="mdi-file-upload-outline"></v-file-input>
                        </v-col>
                        <v-col cols="12" md="6">
                            <v-text-field :readonly="userInfo.userType != 1 && dialogType == dialogEnum.update" v-model="editedItem.repairRemark" label="整改建议" required></v-text-field>
                        </v-col>  
                    </v-row>
                </v-card-text>
                <v-card-actions>
                    <v-btn color="primary" variant="text" @click="close">关闭</v-btn>
                    <v-btn color="primary" variant="text" @click="save" v-if="userInfo.userType == 3 || dialogType == dialogEnum.create">确定</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
        <!-- <v-btn prepend-icon="mdi-download" v-on:click="clickDownloadWord">模板</v-btn> -->
        <v-tooltip text="下载漏洞模板" location="bottom">
            <template v-slot:activator="{ props }">
                <v-btn icon="mdi-download" v-on:click="clickDownloadWord" v-bind="props"></v-btn>
            </template>
        </v-tooltip>
        <v-dialog v-model="isShowDeleteDialog" max-width="500px">
            <v-card>
                <v-card-title class="text-h5">确定删除?</v-card-title>
                <v-card-actions>
                    <v-spacer></v-spacer>
                    <v-btn color="blue-darken-1" variant="text" @click="clickCloseDelete">取消</v-btn>
                    <v-btn color="blue-darken-1" variant="text" @click="clickDeleteConfirm">确定</v-btn>
                    <v-spacer></v-spacer>
                </v-card-actions>
            </v-card>
        </v-dialog>
    </v-toolbar>
  <!--  分页文本待更换   items-per-page-text="每页数量"-->
    <v-data-table-server :search="search" :items-per-page="itemsPerPage" :headers="headers" :items-length="totalItems"
    :items="items"
    :loading="loading"
    class="elevation-1"
    items-per-page-text="每页数量"
    @update:options="loadItems">
        <template v-slot:item.num="{ index }">
            <span>{{ index + 1 }}</span>
        </template>
        <template v-slot:item.activityId="{ item }">
            <span v-for="k in activityList" v-show="k.id == item.activityId">
                {{ k.name }}
            </span>
        </template>
        <template v-slot:item.attackUserId="{ item }">
            <span v-for="k in userList" v-show="k.id == item.attackUserId">
                {{ k.nickname }}
            </span>
        </template>
        <template v-slot:item.attackId="{ item }">
            <span v-for="k in attackList" v-show="k.id == item.attackId">
                {{ k.companyName }}
            </span>
        </template>
        <template v-slot:item.defendId="{ item }">
            <span v-for="k in defendList" v-show="k.id == item.defendId">
                {{ k.companyName }}
            </span>
        </template>
        <template v-slot:item.scoreStatus="{ item }">
            <v-chip v-if="item.scoreStatus == 1" color="red">
                待打分
            </v-chip>
            <v-chip v-if="item.scoreStatus == 2" color="green">
                已打分
            </v-chip>
        </template>
        <template v-slot:item.actions="{ item }">
            <v-btn icon="mdi-pencil" variant="text" @click="clickEdit(item)"></v-btn>
            <v-tooltip text="下载漏洞信息" location="bottom">
                <template v-slot:activator="{ props }">
                    <v-btn icon="mdi-download" variant="text" v-on:click="clickDownload(item)" v-bind="props"></v-btn>
                </template>
            </v-tooltip>
            <v-tooltip text="查看漏洞信息" location="bottom">
                <template v-slot:activator="{ props }">
                    <v-btn icon="mdi-folder-zip" variant="text" v-on:click="clickCheck(item)" v-bind="props"></v-btn>
                </template>
            </v-tooltip>
            <v-tooltip text="打分" location="bottom" v-if="userInfo.userType == 2 && item.scoreStatus == 1">
                <template v-slot:activator="{ props }">
                    <v-btn icon="mdi-numeric-10-circle" variant="text" v-on:click="clickScore(item)" v-bind="props"></v-btn>
                </template>
            </v-tooltip>
            <!-- <v-btn icon="mdi-folder-zip" variant="text" @click="clickZip(item)"></v-btn> -->
            <!-- <v-btn variant="tonal" @click="clickCheck(item)">漏洞信息</v-btn> -->
            <!-- <v-btn v-if="userInfo.userType == 2 && item.scoreStatus == 1" variant="tonal" @click="clickScore(item)">打分</v-btn> -->
        </template>
    </v-data-table-server>
    
    <v-dialog v-model="zipShow" max-width="500px">
        <v-card>
            <v-card-title>下载报告</v-card-title>
            <v-card-text>
                <v-text-field v-model="zipItem.contactName" label="报告人姓名"></v-text-field>
                <v-text-field v-model="zipItem.contactPhone" label="报告人手机号"></v-text-field>
            </v-card-text>
            <v-card-actions>
                <v-btn color="primary" variant="text" @click="zipShow = false">关闭</v-btn>
                <v-btn color="primary" variant="text" @click="saveZip">打分</v-btn>
            </v-card-actions>
        </v-card>
    </v-dialog>

    <v-dialog v-model="htmlShow" max-width="1000px" fullScreen>
        <v-card>
            <v-toolbar density="compact">
                <v-btn icon="mdi-close" @click="htmlShow = false"></v-btn>
                <v-toolbar-title>漏洞信息</v-toolbar-title>
            </v-toolbar>
            <VueOfficeDocx :src="docxSrc" />
        </v-card>
    </v-dialog>

    <v-dialog v-model="scoreShow" max-width="500px">
        <v-card
        :title="'攻方企业：' + scoreItem.attackName"
        :text="'漏洞企业：' + scoreItem.defendName"
        :subtitle="'时间：' + scoreItem.createTime">
            <v-card-title>
                <div style="margin: 0 10px;">
                    {{ scoreItem.activityName }}
                </div>
            </v-card-title>
            <v-card-text>
                <v-text-field v-model="score" :clearable="true" hide-details label="打分"></v-text-field>                
            </v-card-text>
            <v-card-actions>
                <v-btn color="primary" variant="text" @click="scoreShow = false">关闭</v-btn>
                <v-btn color="primary" variant="text" @click="saveScroe(scoreItem)">打分</v-btn>
            </v-card-actions>
        </v-card>
    </v-dialog>
</template>

<style scoped lang="less">

</style>
